<?php

namespace app\admin\model;
use think\Model;
use fast\Tree;

class Autoplan extends Model
{
    // 表名
    /**
     * @var string 数据表名
     */
    public $name = 'course_table_autoplan';
    
    /**
     * @var string 表前缀
     */
    public $prefix_new = 'fa_';
    
    // 自动写入时间戳字段
    /**
     * @var string|int 是否自动写入时间戳
     */
    protected $autoWriteTimestamp = 'int';

    // 定义时间戳字段名
    /**
     * @var string 创建时间字段名
     */
    protected $createTime = 'create_time';
    
    /**
     * @var string 更新时间字段名
     */
    protected $updateTime = 'update_time';
    
    /**
     * @var bool 是否假删除
     */
    protected $falseDelete = false;

    /**
     * 获取班级ID文本
     * @param string $value 班级ID值
     * @param array $data 数据数组
     * @return string 班级名称列表
     */
    public function getClasses_idTextAttr($value, $data=[])
    {
        $s = [];
        if($value) {
            $nn = preg_split("/,/", $value);
        } else {
            $nn = [];
        }
        // 获取班级信息
        $classes = \think\Db::name('classes')->column('name', 'id');
        foreach($nn as $classId) {
            if($classId == "") continue;
            if(isset($classes[$classId])) $s[] = $classes[$classId];
        }
        return join(",", $s);
    }

    /**
     * 获取教学点ID文本
     * @param string $value 教学点ID值
     * @param array $data 数据数组
     * @return string 教学点名称列表
     */
    public function getOcation_idTextAttr($value, $data=[])
    {
        $s = [];
        if($value) {
            $nn = preg_split("/,/", $value);
        } else {
            $nn = [];
        }
        // 获取教学点信息
        $ocations = \think\Db::name('ocation')->column('name', 'id');
        foreach($nn as $ocationId) {
            if($ocationId == "") continue;
            if(isset($ocations[$ocationId])) $s[] = $ocations[$ocationId];
        }
        return join(",", $s);
    }

    /**
     * 获取自动排课ID文本
     * @param string $value 自动排课ID值
     * @param array $data 数据数组
     * @return string 自动排课名称列表
     */
    public function getAutoplan_idTextAttr($value, $data=[])
    {
        if($value) {
            $nn = preg_split("/,/", $value);
        } else {
            $nn = [];
        }
        $s = [];
        for($i=0; $i<count($nn); $i++) {
            if($nn[$i] == "") continue;
            $r = Model("Autoplan")->get(["id" => $nn[$i]]);
            if($r) $s[] = $r['name'];
        }
        return join(",", $s);
    }

    /**
     * 获取课程类型文本
     * @param string $value 课程类型值
     * @param array $data 数据数组
     * @return string 课程类型文本
     */
    public function getCourse_typeTextAttr($value, $data=[])
    {
        $courseTypes = [
            '1' => '公益活动',
            '2' => '社区活动', 
            '3' => '研学活动',
            '4' => '趣味活动'
        ];
        return isset($courseTypes[$value]) ? $courseTypes[$value] : $value;
    }

    /**
     * 获取班级名称
     * @param string $value 班级ID
     * @param array $data 数据数组
     * @return string 班级名称
     */
    public function getClass_idTextAttr($value, $data=[])
    {
        if (empty($value)) {
            return '';
        }
        $class = \think\Db::name('classes')->where('id', $value)->find();
        return $class ? $class['name'] : '';
    }

    /**
     * 获取管理员名称
     * @param string $value 管理员ID
     * @param array $data 数据数组
     * @return string 管理员名称
     */
    public function getAdmin_idTextAttr($value, $data=[])
    {
        if (empty($value)) {
            return '';
        }
        $admin = \think\Db::name('admin')->where('id', $value)->find();
        return $admin ? ($admin['nickname'] ? $admin['nickname'] : $admin['username']) : '';
    }

    /**
     * 获取上课前打卡时间文本
     * @param string $value 打卡时间值
     * @param array $data 数据数组
     * @return string 打卡时间文本
     */
    public function getCheckin_before_classTextAttr($value, $data=[])
    {
        if (empty($value)) {
            return '未设置';
        }
        return $value . '分钟';
    }

    /**
     * 获取上课后打卡时间文本
     * @param string $value 打卡时间值
     * @param array $data 数据数组
     * @return string 打卡时间文本
     */
    public function getCheckin_after_classTextAttr($value, $data=[])
    {
        if (empty($value)) {
            return '未设置';
        }
        return $value . '分钟';
    }

    /**
     * 获取下课后评价时间文本
     * @param string $value 评价时间值
     * @param array $data 数据数组
     * @return string 评价时间文本
     */
    public function getEvaluation_after_classTextAttr($value, $data=[])
    {
        if (empty($value)) {
            return '未设置';
        }
        return $value . '分钟';
    }

    /**
     * 验证给定table_id的项目当前是正式排课还是临时排课
     * @param int $table_id 项目ID
     * @return array 返回详细的排课状态信息
     */
    public function validateScheduleStatus($table_id)
    {
        // 检查正式排课表中是否有记录
        $formalCount = $this->where('table_id', $table_id)->count();
        
        // 检查临时排课表中是否有记录
        $tempCount = model('Autoplantemp')->where('table_id', $table_id)->count();
        
        $result = [
            'table_id' => $table_id,
            'formal_count' => $formalCount,
            'temp_count' => $tempCount,
            'is_formal' => false,
            'is_temp' => false,
            'status' => 'none',
            'message' => ''
        ];
        
        if ($formalCount > 0 && $tempCount == 0) {
            // 正式排课：正式表有记录，临时表没有记录
            $result['is_formal'] = true;
            $result['status'] = 'formal';
            $result['message'] = '该项目为正式排课';
        } elseif ($tempCount > 0 && $formalCount == 0) {
            // 临时排课：临时表有记录，正式表没有记录
            $result['is_temp'] = true;
            $result['status'] = 'temp';
            $result['message'] = '该项目为临时排课';
        } elseif ($formalCount > 0 && $tempCount > 0) {
            // 异常情况：两个表都有记录
            $result['status'] = 'conflict';
            $result['message'] = '数据异常：正式表和临时表都有记录';
        } else {
            // 两个表都没有记录
            $result['status'] = 'none';
            $result['message'] = '该项目未进行排课';
        }
        
        return $result;
    }
    
    /**
     * 判断给定table_id的项目是否为正式排课
     * @param int $table_id 项目ID
     * @return bool
     */
    public function isFormalSchedule($table_id)
    {
        $formalCount = $this->where('table_id', $table_id)->count();
        $tempCount = model('Autoplantemp')->where('table_id', $table_id)->count();
        
        return ($formalCount > 0 && $tempCount == 0);
    }
    
    /**
     * 判断给定table_id的项目是否为临时排课
     * @param int $table_id 项目ID
     * @return bool
     */
    public function isTempSchedule($table_id)
    {
        $formalCount = $this->where('table_id', $table_id)->count();
        $tempCount = model('Autoplantemp')->where('table_id', $table_id)->count();
        
        return ($tempCount > 0 && $formalCount == 0);
    }

    /**
     * 获取日期限制类型文本
     * @param string $value 限制类型值
     * @param array $data 数据数组
     * @return string 限制类型文本
     */
    public function getDateRestrictionTextAttr($value, $data)
    {
        $restrictionTypes = [
            '' => '无限制',
            'workdays' => '仅工作日',
            'weekends' => '仅周末',
            'custom_weekdays' => '自定义周几',
            'specific_dates' => '指定日期'
        ];
        
        $value = isset($data['date_restriction']) ? $data['date_restriction'] : '';
        return isset($restrictionTypes[$value]) ? $restrictionTypes[$value] : $value;
    }

    /**
     * 获取日期限制配置
     * @param string $value 配置值
     * @param array $data 数据数组
     * @return array 配置数组
     */
    public function getRestrictionConfigAttr($value, $data)
    {
        if (empty($value)) {
            return [];
        }
        
        $config = json_decode($value, true);
        return is_array($config) ? $config : [];
    }

    /**
     * 设置日期限制配置
     * @param array $value 配置数组
     * @return string JSON编码后的配置
     */
    public function setRestrictionConfigAttr($value)
    {
        if (is_array($value)) {
            return json_encode($value, JSON_UNESCAPED_UNICODE);
        }
        return $value;
    }

    /**
     * 验证日期是否符合限制条件
     * @param string $date 要验证的日期 (Y-m-d格式)
     * @return array 返回验证结果 ['valid' => bool, 'message' => string]
     */
    public function validateDateRestriction($date, $data = null)
    {
        if (!$data) {
            $data = $this->getData();
        }
        
        $restrictionType = isset($data['date_restriction']) ? $data['date_restriction'] : '';
        if (empty($restrictionType)) {
            return ['valid' => true, 'message' => '无日期限制'];
        }
        
        $config = isset($data['restriction_config']) ? json_decode($data['restriction_config'], true) : [];
        if (!is_array($config)) {
            $config = [];
        }
        
        try {
            $dateTime = new \DateTime($date);
            $dayOfWeek = $dateTime->format('N'); // 1-7 (周一到周日)
            
            switch ($restrictionType) {
                case 'workdays':
                    if ($dayOfWeek >= 6) { // 周六、周日
                        return ['valid' => false, 'message' => '只能选择工作日（周一至周五）'];
                    }
                    break;
                    
                case 'weekends':
                    if ($dayOfWeek < 6) { // 周一至周五
                        return ['valid' => false, 'message' => '只能选择周末（周六、周日）'];
                    }
                    break;
                    
                case 'custom_weekdays':
                    $allowedWeekdays = isset($config['weekdays']) ? $config['weekdays'] : [];
                    if (!in_array($dayOfWeek, $allowedWeekdays)) {
                        $weekdayNames = ['', '周一', '周二', '周三', '周四', '周五', '周六', '周日'];
                        $allowedNames = array_map(function($day) use ($weekdayNames) {
                            return $weekdayNames[$day];
                        }, $allowedWeekdays);
                        return ['valid' => false, 'message' => '只能选择：' . implode('、', $allowedNames)];
                    }
                    break;
                    
                case 'specific_dates':
                    $allowedDates = isset($config['dates']) ? $config['dates'] : [];
                    if (!in_array($date, $allowedDates)) {
                        return ['valid' => false, 'message' => '只能选择指定的日期'];
                    }
                    break;
            }
            
            return ['valid' => true, 'message' => '日期符合限制条件'];
            
        } catch (\Exception $e) {
            return ['valid' => false, 'message' => '日期格式错误'];
        }
    }
    
    /**
     * 检查时间段在指定教学点是否存在冲突
     * @param array $timeSlot 时间段信息，包含year, month, day, startTime, endTime
     * @param int $ocation_id 教学点ID
     * @return array|false 如果存在冲突返回记录，否则返回false ==yzs1013
     */
    public function checkTimeslotOcationFormAutoplan($timeSlot, $ocation_id,$t_id=null)
    {
        $dateStr = $timeSlot['year'] . '-' . $timeSlot['month'] . '-' . $timeSlot['day'];
        $currentStartTime = isset($timeSlot['start_time']) ? $timeSlot['start_time'] : (isset($timeSlot['startTime']) ? $timeSlot['startTime'] : null);
        $currentEndTime = isset($timeSlot['end_time']) ? $timeSlot['end_time'] : (isset($timeSlot['endTime']) ? $timeSlot['endTime'] : null);

        return \think\Db::name('fa_course_table_autoplan')
            ->alias('t')
            ->where('t.ocation_id', $ocation_id)
            ->where('date', $dateStr)
            ->where('t.id',"<>",$t_id)
            ->where(function ($query) use ($currentStartTime, $currentEndTime) {
                // 检查时间段是否有交叉
                $query->whereOr(function ($subQuery) use ($currentStartTime, $currentEndTime) {
                    // 情况1：新时间段的开始时间在已存在时间段内
                    $subQuery->where('t.start_time', '<=', $currentStartTime)
                            ->where('t.end_time', '>', $currentStartTime);
                })->whereOr(function ($subQuery) use ($currentStartTime, $currentEndTime) {
                    // 情况2：新时间段的结束时间在已存在时间段内
                    $subQuery->where('t.start_time', '<', $currentEndTime)
                            ->where('t.end_time', '>=', $currentEndTime);
                })->whereOr(function ($subQuery) use ($currentStartTime, $currentEndTime) {
                    // 情况3：新时间段完全包含已存在时间段
                    $subQuery->where('t.start_time', '>=', $currentStartTime)
                            ->where('t.end_time', '<=', $currentEndTime);
                });
            })
            ->join('eb_classes c1', 't.table_type=1 AND c1.id=t.classes_id', 'LEFT')
            ->join('fa_ocation_class c3', 't.table_type=2 AND c3.id=t.classes_id', 'LEFT')
            ->join('fa_ocation o', 'o.id=t.ocation_id', 'left')
            ->field('t.*,COALESCE(c1.name,c3.name) as class_name,o.name as ocation_name')
            ->find();
    }

    function getTimeslotByClassTime($class_time){
        $timeslot = \think\Db::name('fa_course_table_timeslot')->where('class_time', $class_time)->find();
        return $timeslot;
    }
}